package com.sikaryofficial.backend.controller;

import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sikaryofficial.backend.annotation.Repeat;
import com.sikaryofficial.backend.config.StoreConfig;
import com.sikaryofficial.backend.domain.dto.req.StoreDetailReq;
import com.sikaryofficial.backend.domain.dto.req.StoreEvaluateListReq;
import com.sikaryofficial.backend.domain.dto.req.StoreEvaluateSaveReq;
import com.sikaryofficial.backend.domain.dto.req.StoreNearReq;
import com.sikaryofficial.backend.domain.dto.req.store.StoreNearTop3Req;
import com.sikaryofficial.backend.domain.dto.resp.StoreListDTO;
import com.sikaryofficial.backend.domain.entity.StoreEvaluateExt;
import com.sikaryofficial.backend.domain.vo.store.StoreEvaluateExtObj;
import com.sikaryofficial.backend.manager.StoreEvaluateManager;
import com.sikaryofficial.backend.manager.StoreFollowManager;
import com.sikaryofficial.backend.service.store.StoreCacheService;
import com.sikaryofficial.backend.service.user.UserCacheService;
import com.sikaryofficial.common.core.domain.R;
import com.sikaryofficial.common.core.utils.HiResultUtil;
import com.sikaryofficial.common.core.utils.PageUtil;
import com.sikaryofficial.common.core.web.controller.BaseController;
import com.sikaryofficial.common.core.web.domain.HiResult;
import com.sikaryofficial.common.core.web.domain.PageResult;
import com.sikaryofficial.common.log.annotation.Log;
import com.sikaryofficial.common.log.enums.BusinessType;
import com.zaxxer.hikari.pool.HikariPool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 店铺Controller
 *
 * @author qinjinyuan
 * @date 2023-11-06
 */
@RestController
@RequestMapping("/store")
@Api(tags = "店铺")
@Slf4j
public class StoreController extends BaseController {

    @Autowired
    private StoreEvaluateManager storeSharedManager;
    @Autowired
    private StoreFollowManager storeFollowManager;
    @Autowired
    private StoreCacheService storeCacheService;
    /**
     * 默认半径10公里范围数据
     */
    @Value("${hismk.backend.store.defaultRadius:10}")
    private String radius;
    @Autowired
    private UserCacheService userCacheService;

    @Resource
    private StoreConfig storeConfig;

    @GetMapping("/pickOwnerProduct")
    @ApiOperation("店铺评价-自家销售产品选择列表")
    public R<List<String>> pickOwnerProduct() {
        return R.ok(storeConfig.getSaleOwnerProducts());
    }

    /**
     * 新增店铺分享记录
     */
    @Log(title = "店铺评价记录", businessType = BusinessType.INSERT)
    @PostMapping("/evaluate/add")
    @ApiOperation("店铺评价(分享)添加")
    public HiResult<Boolean> storeEvaluateAdd(@Validated @RequestBody StoreEvaluateSaveReq req) {
        if (CharSequenceUtil.isNotBlank(req.getLongitude()) && CharSequenceUtil.isNotBlank(req.getLatitude())) {
            userCacheService.setUserLocalInfo(Double.parseDouble(req.getLongitude()), Double.parseDouble(req.getLatitude()));
        } else {
            req.setLongitude(null);
            req.setLatitude(null);
        }
        return HiResultUtil.success(storeSharedManager.storeEvaluateAdd(req));
    }

    /**
     * 被分享的零售商店列表
     * <p>
     * 最新分享的商店-分页列表
     */
    @PostMapping("/evaluate/list")
    @ApiOperation("首页-最新被评价的店铺")
    @Repeat
    public PageResult<StoreListDTO> sharedList(@Validated @RequestBody StoreEvaluateListReq req) {
        if (CharSequenceUtil.isBlank(req.getLongitude()) || CharSequenceUtil.isBlank(req.getLatitude())) {
            req.setLongitude(String.valueOf(userCacheService.getUserLocalInfo().getLongitude()));
            req.setLatitude(String.valueOf(userCacheService.getUserLocalInfo().getLatitude()));
        }
        IPage<StoreListDTO> result = storeSharedManager.storeListBySource(req);
        return PageUtil.success(result.getRecords(), result.getTotal());
    }

    /**
     * 附近的商店列表 -基于Redis API实现
     *
     * @param storeNearReq
     * @return
     */
    @PostMapping("/top3")
    @ApiOperation("附近的商店top3")
    @Repeat
    public R<List<StoreListDTO>> top3(@Validated @RequestBody StoreNearTop3Req storeNearReq) {
        if (CharSequenceUtil.isBlank(storeNearReq.getLongitude()) || CharSequenceUtil.isBlank(storeNearReq.getLatitude())) {
            storeNearReq.setLongitude(String.valueOf(userCacheService.getUserLocalInfo().getLongitude()));
            storeNearReq.setLatitude(String.valueOf(userCacheService.getUserLocalInfo().getLatitude()));
        }
        log.info("nearModify:top3 {}", storeNearReq);
        List<StoreListDTO> allShops = storeCacheService.top3(Double.parseDouble(storeNearReq.getLongitude()), Double.parseDouble(storeNearReq.getLatitude()), Double.parseDouble(radius));
        return R.ok(allShops);
    }

    /**
     * 附近的商店列表 -基于Redis API实现
     *
     * @param storeNearReq
     * @return
     */
    @PostMapping("/near")
    @ApiOperation("附近的商店分页列表")
    @Repeat
    public PageResult<StoreListDTO> nearModify(@Validated @RequestBody StoreNearReq storeNearReq) {
        if (CharSequenceUtil.isBlank(storeNearReq.getLongitude()) || CharSequenceUtil.isBlank(storeNearReq.getLatitude())) {
            storeNearReq.setLongitude(String.valueOf(userCacheService.getUserLocalInfo().getLongitude()));
            storeNearReq.setLatitude(String.valueOf(userCacheService.getUserLocalInfo().getLatitude()));
        }
        log.info("nearModify:storeNearReq {}", storeNearReq);
        List<StoreListDTO> allShops = storeCacheService.getNearReal(Double.parseDouble(storeNearReq.getLongitude()), Double.parseDouble(storeNearReq.getLatitude()), Double.parseDouble(radius));
        log.info("nearModify:result:{}", allShops.size());
        // 静态分页
        int fromIndex = (storeNearReq.getPageNum() - 1) * storeNearReq.getPageSize();
        int toIndex = (storeNearReq.getPageNum() - 1) * storeNearReq.getPageSize() + storeNearReq.getPageSize();
        if (fromIndex >= allShops.size()) {
            return PageUtil.success(Collections.EMPTY_LIST, 0);
        }
        return PageUtil.success(allShops.subList(fromIndex, Math.min(toIndex, allShops.size())), allShops.size());
    }

    /**
     * 查询店铺详情
     */
    @PostMapping("/detail")
    @ApiOperation("查询店铺详情")
    @Repeat
    public R<StoreListDTO> detail(@Validated @RequestBody StoreDetailReq req) {
        // 输入参数校验
        if (Objects.isNull(req.getStoreId()) || req.getStoreId() <= 0) {
            return R.ok();
        }
        if (CharSequenceUtil.isBlank(req.getLongitude()) || CharSequenceUtil.isBlank(req.getLatitude())) {
            req.setLongitude(String.valueOf(userCacheService.getUserLocalInfo().getLongitude()));
            req.setLatitude(String.valueOf(userCacheService.getUserLocalInfo().getLatitude()));
        }
        return R.ok(storeSharedManager.findStoreDetail(req));
    }

    /**
     * 查询店铺详情【带回访记录】
     */
    @PostMapping("/detail/followup")
    @ApiOperation("查询店铺详情【带回访记录】")
    @Repeat
    public R<StoreListDTO> detailWithFollowup(@Validated @RequestBody StoreDetailReq req) {
        // 输入参数校验
        if (Objects.isNull(req.getStoreId()) || req.getStoreId() <= 0) {
            return R.ok();
        }
        if (CharSequenceUtil.isBlank(req.getLongitude()) || CharSequenceUtil.isBlank(req.getLatitude())) {
            req.setLongitude(String.valueOf(userCacheService.getUserLocalInfo().getLongitude()));
            req.setLatitude(String.valueOf(userCacheService.getUserLocalInfo().getLatitude()));
        }
        StoreListDTO storeListDTO = storeSharedManager.findStoreDetail(req);
        storeListDTO.setStoreFollows(storeFollowManager.getFollowupList(req.getStoreId()));
        StoreEvaluateExt storeEvaluateExt = storeSharedManager.getEvaluateExt(req.getStoreId());
        StoreEvaluateExtObj extObj = Objects.nonNull(storeEvaluateExt) ? storeEvaluateExt.getExtObj() : null;
        storeListDTO.setExtObj(extObj);
        return R.ok(storeListDTO);
    }

}
